package com.lzq.badminton.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lzq.badminton.Exception.SystemException;
import com.lzq.badminton.dto.UserLoginDto;
import com.lzq.badminton.enums.AppHttpCodeEnum;
import com.lzq.badminton.properties.JwtProperties;
import com.lzq.badminton.properties.WeChatProperties;
import com.lzq.badminton.security.WxAuthenticationManager;
import com.lzq.badminton.security.WxAuthenticationToken;
import com.lzq.badminton.service.UserService;
import com.lzq.badminton.service.WxLoginService;
import com.lzq.badminton.utils.HttpClientUtil;
import com.lzq.badminton.utils.JwtUtil;
import com.lzq.badminton.utils.RedisCache;
import com.lzq.badminton.vo.DoubleToken;
import com.lzq.badminton.vo.ResponseResult;
import com.lzq.badminton.vo.UserLoginVO;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class WxLoginServiceImpl implements WxLoginService {
    @Autowired
    private WxAuthenticationManager authenticationManager;

    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private WeChatProperties weChatProperties;

    @Autowired
    private UserService userService;

//    @Autowired
//    private RedisCache redisCache;

    @Override
    public ResponseResult login(UserLoginDto userLoginDto){

        String openid = getOpenid(userLoginDto.getCode());
        if(StringUtils.isEmpty(openid)) {
            System.out.println("openId是空的");
            throw new SystemException(AppHttpCodeEnum.LOGIN_ERROR);
        }
        WxAuthenticationToken wxAuthenticationToken = new WxAuthenticationToken(openid, userLoginDto.getName(), userLoginDto.getAvatar(), userLoginDto.getPhone());
        WxAuthenticationToken authenticate = (WxAuthenticationToken) authenticationManager.authenticate(wxAuthenticationToken);
        //判断是否认证通过
        if(Objects.isNull(authenticate)){
            System.out.println("认证是空的!!!!!");
            throw new SystemException(AppHttpCodeEnum.LOGIN_ERROR);
        }
        Long userId = authenticate.getUserId();
        String openId = authenticate.getOpenId();



//         写回token
        Map<String, Object> claims = new HashMap<>();
        claims.put("openId", openId);
        claims.put("userId", userId);
        String accessToken = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);

//        //把用户信息存入redis 设置过期时间十五分钟
//        redisCache.setCacheObject("WxToken:"+accessToken, userId, 15, TimeUnit.MINUTES);

        //生成refreshToken
        String refreshToken = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl() * 96, claims);

        UserLoginVO userLoginVO = new UserLoginVO(userId, openId, accessToken, refreshToken);

        return ResponseResult.okResult(userLoginVO);
    }

    @Override
    public DoubleToken refresh(String refreshToken) {
        DoubleToken refresh = null;
        try {
            refresh = JwtUtil.refresh(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), refreshToken);
        } catch (Exception e) {
            if (e instanceof ExpiredJwtException) {
                throw new SystemException(AppHttpCodeEnum.R_TOKEN_ERROR);
            }
        }
        return refresh;
    }

    private String getOpenid(String code) {
        System.out.println("code:" + code);
        //调用微信接口服务，获取当前微信用户的openid
        Map<String, String> map = new HashMap<>();
        map.put("appid", weChatProperties.getAppid());
        map.put("secret", weChatProperties.getSecret());
        map.put("js_code", code);
        map.put("grant_type", "authorization_code");
        String json = HttpClientUtil.doGet(weChatProperties.getWxlogin(), map);

        JSONObject jsonObject = JSON.parseObject(json);
        String openid = jsonObject.getString("openid");
        return openid;
    }
}
